package net.expectx.pay.controller;

import com.alibaba.fastjson.JSON;
import net.expectx.common.single.base.BaseResult;
import net.expectx.common.single.third.ali.AliOssUtil;
import net.expectx.common.single.util.CommonUtil;
import net.expectx.common.single.util.PropertiesFileUtil;
import net.expectx.pay.common.AdminConstants;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.fileupload.util.Streams;
import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.io.*;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @author lj
 * 封装上传文件工具类
 */
@Controller
@RequestMapping("/manager/file")
public class ExpectXFileController {


    @RequestMapping(value="/upload")
    public void upload(HttpServletRequest request,HttpServletResponse response) throws IOException{
        PrintWriter writer = null;
        Map<String, String> extMap = CommonUtil.allowUploadFileExt();
        long maxSize = 2*1048576;
        String path = request.getContextPath();
        int serverPort=request.getServerPort();

        // 文件大小限制
        String sizeLimit = request.getParameter("sizeLimit");
        if(StringUtils.isNotBlank(sizeLimit)) {
            int limit = Integer.parseInt(sizeLimit);
            int maxLimit = 300;
            if(limit > 0 && limit <= maxLimit) {
                maxSize = limit * 1048576;
            }
        }

        String basePath = request.getScheme()+"://"+request.getServerName();
        if(AdminConstants.HTTP_PORT_DEFAULT == serverPort){
            basePath+="/"+path+"/";
        }else{
            basePath+=":"+serverPort+path+"/";
        }
        Map<String,Object>resultMap=new HashMap<String, Object>(2);
        boolean flag=false;
        if(!ServletFileUpload.isMultipartContent(request)){
            printlnError(response,"请选择文件");
            return;
        }
        /**
         * 上传的文件类型
         */
        String dirName = request.getParameter("fileType");
        if (dirName == null) {
            dirName = "images";
        }
        if(!extMap.containsKey(dirName)){
            printlnError(response,"目录名不正确");
            return;
        }

        String fileUrl = "";
        /**
         * 文件存放的目录
         */
        String catalog = request.getParameter("catalog");
        String root=request.getParameter("root");
        if (null==root){
            root=AdminConstants.DEFAULT_FILE_ROOT;
        }

        String savePath = request.getSession().getServletContext().getRealPath(
                "/")
                + "/upload/" +root+"/"+dirName+"/"+catalog + "/";
        File tempDirPath = new File(savePath);
        if (!tempDirPath.exists()) {
            tempDirPath.mkdirs();
        }
        String saveUrl = "upload/" +root+"/"+dirName+"/"+ catalog + "/";
        savePath += "/";
        File dirFile = new File(savePath);
        if (!dirFile.exists()) {
            dirFile.mkdirs();
        }
        DiskFileItemFactory fac = new DiskFileItemFactory();
        ServletFileUpload upload = new ServletFileUpload(fac);
        /**
         * 文件列表
         */
        List fileList = null;
        try {
            fileList = upload.parseRequest(request);
        } catch (FileUploadException ex) {
            ex.printStackTrace();
            return;
        }
        /**
         * 自定义文件名
         */
        String name=request.getParameter("name");

        /**
         * 定义上传文件的比例
         * w 宽 h 高
         */
        String width=request.getParameter("w");
        String height=request.getParameter("h");

        /**
         * 是否存储到云服务器
         * alioss  阿里云OSS
         */
        String oss=request.getParameter("oss");

        String originName=request.getParameter("originName");

        String videoDuration=request.getParameter("videoDuration");

        String imageName = null;
        Iterator<FileItem> it = fileList.iterator();

        while (it.hasNext()) {
            FileItem item = it.next();
            String fileName = item.getName();
            if (!item.isFormField()) {
                if(item.getSize() > maxSize){
                    printlnError(response,"上传文件大小超过限制。");
                    return;
                }
                /**
                 * 检查扩展名
                 */
                String fileExt = fileName.substring(fileName.lastIndexOf(".") + 1).toLowerCase();
                System.out.println(fileExt+"===="+dirName);
                if(!Arrays.<String>asList(extMap.get(dirName).split(",")).contains(fileExt)){
                    printlnError(response,"上传文件扩展名是不允许的扩展名。\n只允许" + extMap.get(dirName) + "格式。");
                    return;
                }
                String extName = item.getName().substring(
                        item.getName().lastIndexOf("."));
                if(originName!=null){
                    imageName=item.getName();
                    resultMap.put("fileName",item.getName());
                }else{
                    if (name!=null) {
                        imageName=name+extName;
                    }else{
                        SimpleDateFormat df = new SimpleDateFormat("yyyyMMddHHmmssSS");
                        imageName = df.format(new Date()) + "_"
                                + new Random().nextInt(1000) + extName;
                    }
                }

                if(null!=width&&null!=height){
                    if(width.length()>0&&height.length()>0){
                        double w=Integer.parseInt(width);
                        double h=Integer.parseInt(height);
                        BufferedImage bufferedImage=ImageIO.read(item.getInputStream());
                        double bw=bufferedImage.getWidth();
                        double bh=bufferedImage.getHeight();
                        if ((w/h)!=(bw/bh)) {
                            printlnError(response,"上传文件比例必须为"+w+":"+h+"。");
                            return;
                        }
                    }
                }

                BufferedInputStream in = new BufferedInputStream(item.getInputStream());
                if(null!=oss){
                    if("alioss".equals(oss)){
                        BaseResult baseResult= AliOssUtil.upload(root,catalog,imageName,in);
                        if (!baseResult.isSuccess()){
                            printlnError(response,baseResult.getMessage());
                            return;
                        }else{
                            fileUrl=((Map)baseResult.getData()).get("fileUrl").toString();
                        }

                    }else{
                        BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(new File(dirFile + "/"+ imageName)));
                        fileUrl = basePath + saveUrl + imageName;
                        Streams.copy(in, out, true);

                    }
                }else{
                    BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(new File(dirFile + "/"+ imageName)));
                    fileUrl = PropertiesFileUtil.getInstance("config").get("file.sources.url")+ saveUrl + imageName;
                    Streams.copy(in, out, true);

                }
                flag=true;
                resultMap.put("url",fileUrl);

            }
        }
        if (flag){
            printlnSuccess(response,resultMap);
        }else{
            printlnError(response,"文件上传失败");
        }
    }
    @RequestMapping(value="/delete")
    public void delete(HttpServletRequest request,HttpServletResponse response) throws IOException{
        String rootPath = request.getSession().getServletContext().getRealPath("/")+"/";
        String filePath=request.getParameter("filePath");
        Map result=new HashMap(2);
        boolean flag=false;
        String message=null;
        /*String aliossPath="http://"+AdminConstants.ALIYUN_OSS_BUCKNAME+"."+AdminConstants.ALIYUN_OSS_ENDPOINT+"/";
        String basePath = request.getScheme()+"://"+request.getServerName();
        String path = request.getContextPath();
        Integer serverPort=request.getServerPort();
        if(AdminConstants.HTTP_PORT_DEFAULT == serverPort){
            basePath+="/"+path+"/";
        }else{
            basePath+=":"+serverPort+path+"/";
        }
        if (filePath.indexOf(basePath)==0){
            File file=new File(rootPath+filePath.substring(basePath.length()));
            if(file.exists()){
                flag=file.delete();
                if (!flag) {
                    message="删除失败";
                }
            }else{
                message="文件不存在";
            }
        }else if(filePath.indexOf(aliossPath)==0){
            OSSClient client = new OSSClient(AdminConstants.ALIYUN_OSS_ENDPOINT, AdminConstants.ALIYUN_OSS_ACCESSKEYID, AdminConstants.ALIYUN_OSS_ACCESSKEYSECRET);
            client.deleteObject(AdminConstants.ALIYUN_OSS_BUCKNAME,filePath.substring(aliossPath.length()));
            flag=true;
            client.shutdown();
        }*/
        result.put("flag", flag);
        result.put("msg",message);
        PrintWriter writer = encodehead(request, response);
        writer.println(JSON.toJSONString(result));
        writer.close();
    }

    private PrintWriter encodehead(HttpServletRequest request,
                                   HttpServletResponse response) throws IOException {
        request.setCharacterEncoding("utf-8");
        response.setContentType("text/html; charset=utf-8");
        return response.getWriter();
    }
    public static void printlnObject(HttpServletResponse response,Object object){
        PrintWriter writer=getWriter(response);
        writer.println(JSON.toJSONString(object));
        writer.flush();
        writer.close();
    }

    public static void printlnSuccess(HttpServletResponse response,Object object){
        Map<String,Object>resultMap=new HashMap<String, Object>(2);
        resultMap.put("success",true);
        resultMap.put("code",200);
        resultMap.put("message","成功");
        resultMap.put("data",object);
        printlnObject(response,resultMap);
    }
    public static void printlnError(HttpServletResponse response,String error){
        System.out.println(error);
        Map<String,Object>resultMap=new HashMap<String, Object>(2);
        resultMap.put("success",false);
        resultMap.put("code",0);
        resultMap.put("message",error);
        printlnObject(response,resultMap);
    }
    public static PrintWriter getWriter(HttpServletResponse response){
        response.setCharacterEncoding("UTF-8");
        PrintWriter writer = null;
        try {
            writer = response.getWriter();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return writer;
    }
}
